//
// Created by jinling on 2025/6/25.
//
#pragma once
#include"Logger.h"
#include "TTime.h"

#include <sstream>
#include <string.h>
#include <unistd.h>
#include<sys/syscall.h>

namespace  tmms
{
    namespace  base
    {
        extern Logger * g_logger;
        class LogStream //打印的类，在logstream的析构函数里面打印，往 logger_中写入自己的，stream_
        {
        public:
            LogStream(Logger * logger,const  char * file, int line, LogLevel level,const char * func);
            ~LogStream(); //统一在析构函数中才把日志写到文件中，在此之前将他一直存在内存中就好了

            template <class T> //但是  为何模板一定要放在.h文件中？？？ ，放在.cpp中为何会报错？
            LogStream &  operator<<(const T& value) //返回一个LogStream的引用
            {
                    stream_<< value;
                    return *this;
            }
            /*问题：当模板在一个.cpp 文件中定义，而在另一个.cpp 文件中使用时，编译器在编译使用模板的文件时，可能无法看到模板的完整定义，导致实例化失败*/

        private:
            std::ostringstream stream_;
            Logger * logger_{nullptr};
        };
    }
}



#define LOG_TRACE  \
    if(tmms::base::g_logger->GetLogLevel() <= tmms::base::KTrace)  \
        tmms::base::LogStream(tmms::base::g_logger,__FILE__,__LINE__,tmms::base::KTrace,__func__) 
#define LOG_DEBUG \
    if(tmms::base::g_logger->GetLogLevel() <= tmms::base::KDebug)  \
    tmms::base::LogStream(tmms::base::g_logger,__FILE__,__LINE__,tmms::base::KDebug,__func__)

#define LOG_INFO  \
    if(tmms::base::g_logger->GetLogLevel() <= tmms::base::KInfo)  \
    tmms::base::LogStream(tmms::base::g_logger,__FILE__,__LINE__,tmms::base::KInfo,__func__)

#define LOG_WARN \
    tmms::base::LogStream(tmms::base::g_logger,__FILE__,__LINE__,tmms::base::KWarn,__func__)

#define LOG_ERROR  tmms::base::LogStream(tmms::base::g_logger,__FILE__,__LINE__,tmms::base::KMaxNumOfLogLevel,__func__)



// //使用：
// using namespace  tmms::base;
//
// void TestLog()
// {
//     LOG_TRACE << "test treace";
// }
//
// int main (int argc, char **grgv)
// {
//     tmms::base::g_logger+ new LOgger( new FileLogPter( )-> );
//     tmms::base::g_logger->SetLogLevel((KTrace));
//     TestLog();
//     return 0;
// }
